package com.ytjj.qmyx.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.ytjj.common.exception.ApiException;
import com.ytjj.qmyx.admin.dao.CategoryNowDao;
import com.ytjj.qmyx.admin.dao.FrontCategoryDao;
import com.ytjj.qmyx.admin.dao.ProductCategoryDao;
import com.ytjj.qmyx.admin.mapper.CategoryFromExcelOrangeMapper;
import com.ytjj.qmyx.admin.mapper.CategoryNowMapper;
import com.ytjj.qmyx.admin.mapper.FrontCategoryMapper;
import com.ytjj.qmyx.admin.mapper.ProductAndCategoryMapper;
import com.ytjj.qmyx.admin.model.*;
import com.ytjj.qmyx.admin.model.request.FrontCategoryRequest;
import com.ytjj.qmyx.admin.model.response.CategoryNowResponse;
import com.ytjj.qmyx.admin.model.response.FrontCategoryResponse;
import com.ytjj.qmyx.admin.model.response.ProductCategoryResp;
import com.ytjj.qmyx.admin.service.FrontCategoryService;
import com.ytjj.qmyx.mall.mapper.BankerProductMapper;
import com.ytjj.qmyx.mall.mapper.ProductCategoryMapper;
import com.ytjj.qmyx.mall.mapper.ProductMapper;
import com.ytjj.qmyx.mall.model.BankerProduct;
import com.ytjj.qmyx.mall.model.Product;
import com.ytjj.qmyx.mall.model.ProductCategory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 
 * 
 * @description:
 */
@Service
@Slf4j
public class FrontCategoryServiceImpl implements FrontCategoryService {

    @Resource(name = "adminFrontCategoryMapper")
    FrontCategoryMapper frontCategoryMapper;

    @Autowired
    CategoryFromExcelOrangeMapper categoryFromExcelOrangeMapper;

    @Autowired
    CategoryNowMapper categoryNowMapper;

    @Autowired
    CategoryNowDao categoryNowDao;

    @Autowired
    ProductMapper productMapper;

    @Autowired
    ProductAndCategoryMapper productAndCategoryMapper;

    @Autowired
    FrontCategoryDao frontCategoryDao;

    @Autowired
    ProductCategoryMapper productCategoryMapper;

    @Autowired
    ProductCategoryDao productCategoryDao;

    @Autowired
    BankerProductMapper bankerProductMapper;

    @Autowired
    ProductCategoryServiceImpl productCategoryServiceImpl;


    @Override
    public List<FrontCategory> getCategoryByPid(FrontCategory FrontCategory) {
        FrontCategoryExample frontCategoryExample = new FrontCategoryExample();
        frontCategoryExample.createCriteria().andPidEqualTo(FrontCategory.getId()).andIsDeleteEqualTo((byte)0);
        frontCategoryExample.setOrderByClause("isnull(sort),sort asc");
        return frontCategoryMapper.selectByExample(frontCategoryExample);
    }

    /**
    * 获取当前分类详情
    * @param frontCategoryRequest:
    * @returns: com.ytjj.common.api.CommonPage<com.ytjj.qmyx.admin.model.response.FrontCategoryResponse>
    * 
    */
    @Override
    public FrontCategoryResponse getCategoryDetailById(FrontCategoryRequest frontCategoryRequest) {
        //1.获得前端分类明细
        FrontCategoryResponse frontCategoryResponses = frontCategoryDao.getCategoryDetailById(frontCategoryRequest.getId());
        //绑定的分类数
        int count = 0;
        //2.获得一二三级分类的集合
        List<ProductCategoryResp> productCategoryResps = getCategoryTree(frontCategoryResponses.getCategoryList());
        if (CollectionUtils.isNotEmpty(productCategoryResps)) {
            //循环一级分类
            for (ProductCategoryResp item2 : productCategoryResps) {
                //得到二三级分类
                List<ProductCategoryResp> cn2 = item2.getChildProductCategory();
                //如果一级分类下没有分类了，则直接累加count；否则循环二级分类
                if (CollectionUtils.isNotEmpty(cn2)) {
                    //循环二级分类
                    for (ProductCategoryResp item3 : cn2) {
                        //得到三级分类
                        List<ProductCategoryResp> cn3 = item3.getChildProductCategory();
                        //如果二级分类下没有分类了，则直接累加count；否则累加三级分类
                        if (CollectionUtils.isNotEmpty(cn3)) {
                            //循环三级分类
                            for (ProductCategoryResp item4 : cn3) {
                                //直接累加三级分类数量
                                count += 1;
                            }
                        } else {
                            //直接累加二级分类数量
                            count += 1;
                        }
                    }
                } else {
                    count += 1;
                }
            }
        }
        frontCategoryResponses.setBindNum(count);
        return frontCategoryResponses;
    }

    /**
    * 删除前台分类
    * @param id:
    * @returns: boolean
    * 
    */
    @Override
    public int delById(Integer id) {
        return frontCategoryMapper.deleteByPrimaryKey(id);
    }

    /**
    * 处理表category_from_excel_orange,最终变成有层级关系的分类表category_now
    * @param :
    * @returns: boolean
    * 
    */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean dealExcelCategory() {
        //todo 商品与分类建立映射后如果已再使用，则不能使用此方法，否则会有重复的映射关系。只能在后台手动修改分类信息
        CategoryFromExcelOrangeExample categoryFromExcelOrangeExample = new CategoryFromExcelOrangeExample();
        categoryFromExcelOrangeExample.createCriteria().andFirstTitleIsNotNull();
        //1.导入的Excel分类数据
        List<CategoryFromExcelOrange> categoryFromExcelOranges = categoryFromExcelOrangeMapper.selectByExample(categoryFromExcelOrangeExample);
        //2.删除当前category_now分类表的数据
        categoryNowMapper.deleteByExample(new CategoryNowExample());
        //3.设置id从3万自增
        categoryNowDao.alterIncrement();
        //一级分类
        Map<String, List<CategoryFromExcelOrange>> result = categoryFromExcelOranges.stream().collect(Collectors.groupingBy(e -> e.getFirstTitle()));
        categoryFromExcelOranges.stream().collect(Collectors.groupingBy(CategoryFromExcelOrange::getFirstTitle, Collectors.toList()));
        for (Map.Entry<String, List<CategoryFromExcelOrange>> entry : result.entrySet()) {
            CategoryNow categoryNow1 = new CategoryNow();
            if(StringUtils.isNotEmpty(entry.getKey())){
                categoryNow1.setPid(0);
                categoryNow1.setTitle(entry.getKey());
                categoryNow1.setGrade(1);
                categoryNowMapper.insertSelective(categoryNow1);
            }
            //二级分类
            List<CategoryFromExcelOrange> list2 = entry.getValue();
            Map<String, List<CategoryFromExcelOrange>> result2 = list2.stream().collect(Collectors.groupingBy(e -> e.getSecondTitle()));
            for (Map.Entry<String, List<CategoryFromExcelOrange>> entry2 : result2.entrySet()) {
                CategoryNow categoryNow2 = new CategoryNow();
                if(StringUtils.isNotEmpty(entry2.getKey())){
                    categoryNow2.setPid(categoryNow1.getId());
                    categoryNow2.setTitle(entry2.getKey());
                    categoryNow2.setGrade(2);
                    categoryNowMapper.insertSelective(categoryNow2);
                }
                //三级分类
                List<CategoryFromExcelOrange> list3 = entry2.getValue();
                Map<String, List<CategoryFromExcelOrange>> result3 = list3.stream().collect(Collectors.groupingBy(e -> e.getThirdTitle()));
                for (Map.Entry<String, List<CategoryFromExcelOrange>> entry3 : result3.entrySet()) {
                    CategoryNow categoryNow3 = new CategoryNow();
                    if(StringUtils.isNotEmpty(entry3.getKey())){
                        categoryNow3.setPid(categoryNow2.getId());
                        categoryNow3.setTitle(entry3.getKey());
                        categoryNow3.setGrade(3);
                        categoryNowMapper.insertSelective(categoryNow3);

                        if(entry3.getValue().size()==1 ){
                            String fourTitle = entry3.getValue().get(0).getOldThirdTitle();
                            if(StringUtils.isNotEmpty(fourTitle)){
                                //四级分类
                                CategoryNow categoryNow4 = new CategoryNow();
                                categoryNow4.setPid(categoryNow3.getId());
                                categoryNow4.setTitle(fourTitle);
                                categoryNow4.setGrade(4);
                                categoryNowMapper.insertSelective(categoryNow4);
                            }
                        }else if(entry3.getValue().size() > 1){
                            log.warn("处理出错，三级分类名称不唯一");
                            log.debug(JSON.toJSONString(entry3.getValue()));
                            throw new ApiException("处理出错，三级分类名称不唯一");
                        }
                    }
                    log.debug("key= " + entry3.getKey() + " and value= "
                            + entry3.getValue());
                }
            }
        }
        return true;
    }


    /**
    * 建立商品与新分类的一个关联关系,保存至中间关联表
    * @param type: 0-建立商品表与分类关联 1-建立供应商商品表与分类关联
    * @returns: boolean
    * 
    */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean bindNowCategory(Integer type){
        //2.建立新的商品和分类关系
        try {
            //新分类集合
            List<Map<String,Object>> maps =  categoryNowDao.selectGradeFour();
            //商品和现有分类的一个关系集合
            List<Map<String,Object>> products =  categoryNowDao.selectBottomIdBind(type);
            products.forEach(e->{
                maps.forEach(e2->{
                    //现有商品绑定的三级分类id和分类表的四级分类id，则保存绑定关系
                    if((e.get("id4").toString()).equals((e2.get("id4").toString()))){
                        ProductAndCategory productAndCategory = new ProductAndCategory();
                        productAndCategory.setProductId(Integer.valueOf(e.get("productId").toString()));
                        productAndCategory.setFirstId(Integer.valueOf(e2.get("id1").toString()));
                        productAndCategory.setSecondId(Integer.valueOf(e2.get("id2").toString()));
                        productAndCategory.setThirdId(Integer.valueOf(e2.get("id3").toString()));
                        productAndCategory.setCreateTime(new Date());
                        productAndCategoryMapper.insert(productAndCategory);
                    }
                });
                log.debug("当前处理的商品是："+e.get("productName").toString());
            });
        } catch (Exception e) {
            throw new ApiException(e);
        }
        return true;
    }

    /**
     * 1.更新商品与新分类的一个关联关系
     * 2.再把分类数据追加到分类表后
    * @param :
    * @returns: boolean
    * 
    */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateNowCategory(){
        try {
            //type: 0-建立商品表与分类关联 1-建立供应商商品表与分类关联
            //新分类集合
            List<Map<String,Object>> maps =  categoryNowDao.selectGradeFour();
            //商品和现有分类的一个关系集合
            List<Map<String,Object>> products =  categoryNowDao.selectBottomIdBind(0);
            products.forEach(e->{
                maps.forEach(e2->{
                    //建立关系，id4-新分类表的四级分类id
                    if((e.get("id4").toString()).equals((e2.get("id4").toString()))){
                        Product product = new Product();
                        product.setId(Integer.valueOf(e.get("productId").toString()));
                        product.setTopCategoryId(Integer.valueOf(e2.get("id1").toString()));
                        product.setCategoryId(Integer.valueOf(e2.get("id2").toString()));
                        product.setBottomCategoryId(Integer.valueOf(e2.get("id3").toString()));
                        //修改新分类的状态
                        CategoryNow categoryNow = new CategoryNow();
                        categoryNow.setStatus(Byte.valueOf(e.get("status").toString()));
                        categoryNow.setId(Integer.valueOf(e2.get("id3").toString()));
                        categoryNowMapper.updateByPrimaryKeySelective(categoryNow);
                        //更新商品的分类Id
                        productMapper.updateByPrimaryKeySelective(product);
                    }
                });
            });

            //供应商商品和现有分类的一个关系集合
            List<Map<String,Object>> bankerProducts =  categoryNowDao.selectBottomIdBind(1);
            bankerProducts.forEach(e->{
                maps.forEach(e2->{
                    //建立关系，id4-新分类表的四级分类id
                    if((e.get("id4").toString()).equals((e2.get("id4").toString()))){
                        BankerProduct bankerProduct = new BankerProduct();
                        bankerProduct.setId(Integer.valueOf(e.get("productId").toString()));
                        bankerProduct.setTopCategoryId(Integer.valueOf(e2.get("id1").toString()));
                        bankerProduct.setCategoryId(Integer.valueOf(e2.get("id2").toString()));
                        bankerProduct.setBottomCategoryId(Integer.valueOf(e2.get("id3").toString()));
                        //更新供应商商品的分类Id
                        bankerProductMapper.updateByPrimaryKeySelective(bankerProduct);
                    }
                });

            });

            //需要将分类数据新增到分类表则放开注释
            CategoryNowExample categoryNowExample = new CategoryNowExample();
            categoryNowExample.createCriteria().andGradeNotEqualTo(4);
            List<CategoryNow> categoryNows =  categoryNowMapper.selectByExample(categoryNowExample);
            List<ProductCategory> productCategories = new ArrayList<>();
            for(CategoryNow item:categoryNows){
                ProductCategory productCategory = new ProductCategory();
                productCategory.setId(item.getId());
                productCategory.setStatus(item.getStatus());
                productCategory.setPid(item.getPid());
                productCategory.setCreateTime(new Date());
                productCategory.setUpdateTime(new Date());
                productCategory.setTitle(item.getTitle());
                productCategory.setIcon(item.getIcon());
                productCategories.add(productCategory);
            }
            productCategoryDao.insertBatch(productCategories);
        } catch (Exception e) {
            throw new ApiException(e);
        }
        return true;
    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public String updateProductCategoryByGrade() {
        String res = "";
        try {
            //type: 0-建立商品表与分类关联 1-建立供应商商品表与分类关联
            //新分类集合，如[{一级分类id，二级分类id，三级分类Id,四级分类Id,一级分类title，二级分类title，三级分类title,四级分类title}]
            List<Map<String,Object>> maps =  categoryNowDao.selectGradeFour();
            AtomicReference<Integer> productCount = new AtomicReference<>(0);
            AtomicReference<Integer> bankerProductCount = new AtomicReference<>(0);
            //商品bottom_category_id小于30000集合
            List<Map<String,Object>> products =  categoryNowDao.getProductAndCategory(30000,0);
            products.forEach(e->{
                maps.forEach(e2->{
                    String title4 = e2.get("t4") == null ? "" : e2.get("t4").toString();
                    //可能包含多个分类名
                    List<String> titles = Arrays.asList(title4.split(",")) ;
                    //建立关系；现有的四级分类名称中包含了商品的bottomCategoryId的名称
                    if(titles.contains(e.get("title").toString())){
                        Product product = new Product();
                        product.setId(Integer.valueOf(e.get("productId").toString()));
                        product.setTopCategoryId(Integer.valueOf(e2.get("id1").toString()));
                        product.setCategoryId(Integer.valueOf(e2.get("id2").toString()));
                        product.setBottomCategoryId(Integer.valueOf(e2.get("id3").toString()));

                        //更新商品的分类Id
                        productMapper.updateByPrimaryKeySelective(product);
                        productCount.getAndSet(productCount.get() + 1);
                    }
                });
            });

            //供应商商品和现有分类的一个关系集合
            List<Map<String,Object>> bankerProducts =  categoryNowDao.getProductAndCategory(30000,1);
            bankerProducts.forEach(e->{
                maps.forEach(e2->{
                    String title4 = e2.get("t4") == null ? "" : e2.get("t4").toString();
                    //可能包含多个分类名
                    List<String> titles = Arrays.asList(title4.split(",")) ;
                    //建立关系；现有的四级分类名称中包含了商品的bottomCategoryId的名称
                    if(titles.contains(e.get("title").toString())){
                        BankerProduct bankerProduct = new BankerProduct();
                        bankerProduct.setId(Integer.valueOf(e.get("productId").toString()));
                        bankerProduct.setTopCategoryId(Integer.valueOf(e2.get("id1").toString()));
                        bankerProduct.setCategoryId(Integer.valueOf(e2.get("id2").toString()));
                        bankerProduct.setBottomCategoryId(Integer.valueOf(e2.get("id3").toString()));
                        //更新供应商商品的分类Id
                        bankerProductMapper.updateByPrimaryKeySelective(bankerProduct);
                        bankerProductCount.getAndSet(bankerProductCount.get()+1);
                    }
                });
            });
            res = "更新的商品数量--->"+productCount.get()+"\n"+"更新的供应商商品数--->"+bankerProductCount.get();
        } catch (Exception e) {
            throw new ApiException(e);
        }
        return res;
    }

    /**
    * 新增或修改前台分类
    * @param frontCategoryRequest:
    * @returns: int
    * 
    */
    @Override
    public int addOrEditFrontCategory(FrontCategoryRequest frontCategoryRequest) {
        String str =  frontCategoryRequest.getCategoryList();
        List<String> strings = new ArrayList<>();
        if(StringUtils.isNotEmpty(str)){
            strings =  Arrays.asList(str.split(","));
        }
        //去重
        List list = new ArrayList();
        for(int i=0;i<strings.size();i++){
            if(!list.contains(strings.get(i))){
                list.add(strings.get(i));
            }
        }
        String lists =  StringUtils.join(list,",");
        frontCategoryRequest.setCategoryList(lists);
        int count = 0;

        if(frontCategoryRequest.getFirstId() != null && frontCategoryRequest.getFirstId() != 0 ){
            if(frontCategoryRequest.getSecondId() != null && frontCategoryRequest.getSecondId() != 0 ){
                if(frontCategoryRequest.getThirdId() != null && frontCategoryRequest.getThirdId() != 0){
                    frontCategoryRequest.setPid(frontCategoryRequest.getThirdId());
                }else{
                    frontCategoryRequest.setPid(frontCategoryRequest.getSecondId());
                }
            }else{
                frontCategoryRequest.setPid(frontCategoryRequest.getFirstId());
            }
        }else{
            frontCategoryRequest.setPid(0);
        }

        if(frontCategoryRequest.getId() != null){//更新
            count = frontCategoryMapper.updateByPrimaryKeySelective(frontCategoryRequest);
        }else{//新增
            frontCategoryRequest.setIsDelete((byte)0);
            frontCategoryRequest.setCreateTime(new Date());
            frontCategoryRequest.setUpdateTime(new Date());
            count = frontCategoryMapper.insert(frontCategoryRequest);
        }
        return count;
    }

    @Override
    public List<Map<String,Object>> getCategoryForFront(Integer id) {
        //1.获得所有的分类菜单
        FrontCategory frontCategory = frontCategoryMapper.selectByPrimaryKey(id);
        String str =  frontCategory.getCategoryList();
        List<ProductCategoryResp> getCategoryResps = getCategoryTree(str);
        List<Map<String,Object>> maps3 = new ArrayList<>();
        getCategoryResps.stream().forEach(e->{
            Map<String,Object> map = new HashMap<>();
            map.put("key",e.getId());
            map.put("title",e.getTitle());
            if(e.getChildProductCategory().size()>0){
                List<Map<String,Object>> maps2 = new ArrayList<>();
                e.getChildProductCategory().stream().forEach(e2->{
                    Map<String,Object> map2 = new HashMap<>();
                    map2.put("key",e2.getId());
                    map2.put("title",e2.getTitle());
                    if(e2.getChildProductCategory().size()>0){
                        List<Map<String,Object>> maps1 = new ArrayList<>();
                        e2.getChildProductCategory().stream().forEach(e3-> {
                            Map<String, Object> map3 = new HashMap<>();
                            map3.put("key", e3.getId());
                            map3.put("title", e3.getTitle());
                            maps1.add(map3);
                        });
                        map2.put("child",maps1);
                    }
                    maps2.add(map2);
                });
                map.put("child",maps2);
            }
            maps3.add(map);
        });
        return maps3;
    }

    /**
    *
    * @param str: 逗号分割的分类Id
    * @returns: java.util.List<com.ytjj.qmyx.admin.model.response.CategoryNowResponse>
    * 
    */
    public List<ProductCategoryResp> getCategoryTree(String str){
        List<Integer> integers = new ArrayList<>();
        if(StringUtils.isNotEmpty(str)){
            List<String> strings = Arrays.asList(str.split(",")) ;
            strings.stream().forEach(e->{
                integers.add(Integer.valueOf(e));
            });
            List<ProductCategoryResp> productCategoryResps =  productCategoryDao.selectCategoryByIds(integers);
            List<ProductCategoryResp> productCategoryResps1 =  productCategoryServiceImpl.getProductCategoryResps(productCategoryResps);
            return  productCategoryResps1;
        }else{
            return  new ArrayList<>();
        }

    }

    public List<CategoryNowResponse> getCategoryResps(List<CategoryNowResponse> categoryList) {
        List<CategoryNowResponse> categoryDTOList = new ArrayList<>();
        //查询所有父类目录
        for(CategoryNowResponse categoryEntity :  categoryList) {
            if(categoryEntity.getPid() == 0) {
                categoryDTOList.add(categoryEntity);
            }
        }
        //查询子目录
        findSubCategory(categoryDTOList, categoryList);

        return categoryDTOList;
    }

    /**
     * 查询子目录
     * @param categoryDTOList
     * @param categoryEntityList
     */
    private void findSubCategory(List<CategoryNowResponse> categoryDTOList, List<CategoryNowResponse> categoryEntityList) {
        //遍历所有父类分类
        for(CategoryNowResponse categoryDTO : categoryDTOList) {
            List<CategoryNowResponse> subCategoryVoList = new ArrayList<>();
            //遍历父类下的cat_id与子类parent_cid相匹配的分类
            for(CategoryNowResponse category : categoryEntityList) {
                if(categoryDTO.getId().equals(category.getPid())) {
                    subCategoryVoList.add(category);
                }
                //设置subCategories
                categoryDTO.setChildProductCategory(subCategoryVoList);
            }
            //递归调用
            findSubCategory(subCategoryVoList, categoryEntityList);
        }
    }

    @Override
    public boolean addCategoryFromNow() {
        //1.获取新的分类表的所有的一二三级分类
        CategoryNowExample categoryNowExample = new CategoryNowExample();
        categoryNowExample.createCriteria().andGradeNotEqualTo(4);
        List<CategoryNow> categoryNows = categoryNowMapper.selectByExample(categoryNowExample);
        ProductCategory productCategory = new ProductCategory();
        for(CategoryNow item : categoryNows){
            productCategory.setId(item.getId());
            productCategory.setPid(item.getPid());
        }
        return true;
    }

    @Override
    public List<FrontCategory> getFrontListByType(String type, Integer isHomeShow) {

        return null;
    }

    @Override
    public boolean setIsHidden(Integer id,Integer status) {
        FrontCategory frontCategory = new FrontCategory();
        frontCategory.setId(id);
        frontCategory.setStatus(status.byteValue());
        int count =  frontCategoryMapper.updateByPrimaryKeySelective(frontCategory);
        return count > 0 ? true : false;
    }

}
